package com.starsray.dynamic.ds.util;

import com.starsray.dynamic.ds.config.DsEncryptorConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jasypt.properties.PropertyValueEncryptionUtils;
import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public final class JasyptUtils {

    private static DsEncryptorConfig encryptorConfig;

    @Autowired
    public void setEncryptorConfig(DsEncryptorConfig encryptorConfig) {
        JasyptUtils.encryptorConfig = encryptorConfig;
    }

    private static final String PASSWORD;

    static {
        String systemProperty = System.getProperty("jasypt.encryptor.password");
        if (StringUtils.isNotBlank(systemProperty)) {
            PASSWORD = systemProperty;
        } else {
            if (encryptorConfig.isBootstrap()) {
                PASSWORD = encryptorConfig.getPassword();
            } else {
                PASSWORD = "DEFAULT";
            }
        }
    }

    private static final BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();

    static {
        basicTextEncryptor.setPassword(PASSWORD);
    }

    /**
     * 私有构造方法，防止被意外实例化
     */
    private JasyptUtils() {
    }

    /**
     * 加密
     *
     * @param plaintext 明文
     * @param password  密码
     * @return String
     */
    public static String encrypt(String password, String plaintext) {
        BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
        basicTextEncryptor.setPassword(password);
        String ciphertext = basicTextEncryptor.encrypt(plaintext);
        return "ENC(" + ciphertext + ")";
    }

    /**
     * 解密
     *
     * @param ciphertext 密文
     * @return String
     */
    public static String decrypt(String ciphertext) {
        if (PropertyValueEncryptionUtils.isEncryptedValue(ciphertext)) {
            return PropertyValueEncryptionUtils.decrypt(ciphertext, basicTextEncryptor);
        }
        log.error("decrypt error:{}", ciphertext);
        throw new RuntimeException("decrypt " + ciphertext + " error!");
    }
}